#!/usr/bin/env pwsh
# Blockchain Middleware API Test Script
# Test all supported blockchain types API interfaces

# Configuration
$BaseUrl = "http://127.0.0.1:5000/api/v1"
$Chains = @("fisco_bcos", "chainmaker", "jdchain", "xuperchain", "thanos")
$ApiKey = "ab0da73580ad5ca829ae1cfd6868107be80f62bccf0ace9bae389388c95e967b"

# Color output function
function Write-ColorOutput {
    param(
        [string]$Message,
        [string]$Color = "White"
    )
    Write-Host $Message -ForegroundColor $Color
}

# Test results statistics
$TestResults = @{
    Total = 0
    Passed = 0
    Failed = 0
    Errors = @()
}
$global:SkippedTests = 0

# Execute API test and record results
function Test-API {
    param(
        [string]$TestName,
        [string]$Uri,
        [string]$Method = "GET",
        [hashtable]$Body = $null,
        [string]$ContentType = "application/json"
    )
    
    $TestResults.Total++
    Write-ColorOutput "`n[TEST] $TestName" "Cyan"
    Write-ColorOutput "Request: $Method $Uri" "Gray"
    
    try {
        $params = @{
            Uri = $Uri
            Method = $Method
            ContentType = $ContentType
            Headers = @{
                "X-API-Key" = $ApiKey
            }
        }
        
        if ($Body) {
            $jsonBody = $Body | ConvertTo-Json -Depth 10
            $params.Body = $jsonBody
            Write-ColorOutput "Request Body: $jsonBody" "Gray"
        }
        
        $response = Invoke-RestMethod @params
        
        # Debug: Show full response
        Write-ColorOutput "Full Response: $($response | ConvertTo-Json -Depth 3 -Compress)" "DarkGray"
        
        if ($response.success -eq $true) {
            Write-ColorOutput "✓ Test Passed" "Green"
            $TestResults.Passed++
            
            # Show response data summary
            if ($response.data) {
                $dataStr = ($response.data | ConvertTo-Json -Depth 2 -Compress)
                if ($dataStr.Length -gt 200) {
                    $dataStr = $dataStr.Substring(0, 200) + "..."
                }
                Write-ColorOutput "Response Data: $dataStr" "DarkGreen"
            }
        } else {
            Write-ColorOutput "✗ Test Failed: $($response.error_message)" "Red"
            $TestResults.Failed++
            $TestResults.Errors += "$TestName - $($response.error_message)"
        }
    }
    catch {
        Write-ColorOutput "✗ Test Exception: $($_.Exception.Message)" "Red"
        $TestResults.Failed++
        $TestResults.Errors += "$TestName - $($_.Exception.Message)"
    }
}

# Start testing
Write-ColorOutput "`n=== Blockchain Middleware API Test Started ===" "Yellow"
Write-ColorOutput "Test Server: $BaseUrl" "Yellow"
Write-ColorOutput "Supported Blockchains: $($Chains -join ', ')" "Yellow"

# 1. Test get supported blockchain list
Write-ColorOutput "`n=== 1. Chain API Test ===" "Magenta"
Test-API "Get Supported Blockchain List" "$BaseUrl/chains"

# 2. Test each blockchain's 5 core interfaces
foreach ($chain in $Chains) {
    Write-ColorOutput "`n--- Testing Blockchain: $chain ---" "Yellow"
    
    # 2.1 Get blockchain information
    Test-API "Get $chain Blockchain Info" "$BaseUrl/chains/$chain/info"
    
    # 2.2 Get latest block
    Test-API "Get $chain Latest Block" "$BaseUrl/chains/$chain/blocks/latest"
    
    # 2.3 Get latest block with transaction details
    Test-API "Get $chain Latest Block (with transactions)" "$BaseUrl/chains/$chain/blocks/latest?with_transactions=true"
    
    # 2.4 Get specific block by ID (using block 1 as example)
    Test-API "Get $chain Block by ID" "$BaseUrl/chains/$chain/blocks/1"
    
    # 2.5 Test smart contract interface - Set contract data
    $setData = @{
        key = "test_key_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
        value = "test_value_$chain"
    }
    Test-API "Set $chain Contract Data" "$BaseUrl/chains/$chain/contracts/set" "POST" $setData
    

    # 2.6 Test smart contract interface - get contract data
    $getData = @{
        key = "aa"
    }
    Test-API "Get $chain Contract Data" "$BaseUrl/chains/$chain/contracts/get" "POST" $getData
    
    # 2.7 Test transaction query interface
    # Only test with chains that have actual transaction data
    if ($chain -eq "thanos") {
        $sampleTxHash = "2a838208c5c0c91a14da23371a4a3c9c0562c9d188a4d4efca9bf0ea330a996f"
        Test-API "Get $chain Transaction by Hash" "$BaseUrl/chains/$chain/transactions/$sampleTxHash" "GET"
    } else {
        Write-ColorOutput "⚠️ Skipping transaction hash test for $chain - no transaction data available" "Yellow"
        $global:SkippedTests++
    }
    
    # 2.8 Test transaction list query
    Test-API "Get $chain Transaction List" "$BaseUrl/transactions?chain_type=$chain&limit=10" "GET"
    
}

# Core API testing completed - 5 chains × 5 interfaces = 25 tests

# 5. Performance test (optional)
Write-ColorOutput "`n=== 5. Performance Test ===" "Magenta"

$performanceTests = @(
    @{ Name = "Concurrent Get Chain Info"; Uri = "$BaseUrl/chains/chainmaker/info" },
    @{ Name = "Concurrent Get Latest Block"; Uri = "$BaseUrl/chains/chainmaker/blocks/latest" }
)

foreach ($perfTest in $performanceTests) {
    Write-ColorOutput "`n[Performance Test] $($perfTest.Name)" "Cyan"
    $startTime = Get-Date
    
    # Execute 5 concurrent requests
    $jobs = 1..5 | ForEach-Object {
        Start-Job -ScriptBlock {
            param($uri)
            try {
                Invoke-RestMethod -Uri $uri -Method GET
                return $true
            } catch {
                return $false
            }
        } -ArgumentList $perfTest.Uri
    }
    
    # Wait for all tasks to complete
    $results = $jobs | Wait-Job | Receive-Job
    $jobs | Remove-Job
    
    $endTime = Get-Date
    $duration = ($endTime - $startTime).TotalMilliseconds
    $successCount = ($results | Where-Object { $_ -eq $true }).Count
    
    Write-ColorOutput "Completion Time: $([math]::Round($duration, 2))ms, Success: $successCount/5" "DarkGreen"
}

# Output test summary
Write-ColorOutput "`n=== Test Summary ===" "Yellow"
Write-ColorOutput "Total Tests: $($TestResults.Total)" "White"
Write-ColorOutput "Passed: $($TestResults.Passed)" "Green"
Write-ColorOutput "Failed: $($TestResults.Failed)" "Red"
Write-ColorOutput "Skipped: $global:SkippedTests" "Yellow"

if ($TestResults.Failed -gt 0) {
    Write-ColorOutput "`nFailed Tests:" "Red"
    foreach ($errorMsg in $TestResults.Errors) {
        Write-ColorOutput "  - $errorMsg" "Red"
    }
}

$successRate = [math]::Round(($TestResults.Passed / $TestResults.Total) * 100, 2)
Write-ColorOutput "`nSuccess Rate: $successRate%" $(if ($successRate -ge 80) { "Green" } elseif ($successRate -ge 60) { "Yellow" } else { "Red" })

if ($TestResults.Failed -eq 0) {
    Write-ColorOutput "`n🎉 All tests passed!" "Green"
    exit 0
} else {
    Write-ColorOutput "`n❌ Some tests failed, please check the logs" "Red"
    exit 1
}